
#include <string.h>
#include "MCU.h"
#include "EnvStore.h"

static __no_init volatile const unsigned char envStore[0x800] @ 0x08003000;

#define EnvStore_Address			(uint32_t)envStore
#define EnvStore_UserInfoAddress	0x08003800 - 8

static volatile uint8_t envLock;
static uint8_t userInfo[8];

int EnvStore_Init(void){
	return 0;
}

void EnvStore_Lock(void){
	envLock = 1;
}

void EnvStore_Unlock(void){
	envLock = 0;
}

int EnvStore_IsLocked(void){
	return envLock;
}

void EnvStore_Read(EnvData_T* e){
	const uint8_t* p = (const uint8_t*)EnvStore_Address;
	
	memcpy(e, p, sizeof(*e));
}

void EnvStore_Write(EnvData_T* e){
	const uint8_t* p = (const uint8_t*)e;	
    /* unlock the flash program/erase controller */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR );
    /* erase the flash pages */
	fmc_page_erase(EnvStore_Address);
	
    uint32_t address = EnvStore_Address;
	uint32_t len = sizeof(*e);
	uint32_t data;
	
    /* program flash */
    while(len > 0){
		if(len > 4){
			memcpy(&data, p, sizeof(data));
			len -= 4;
		}
		else{
			data = 0xFFFFFFFF;
			memcpy(&data, p, len);
			len = 0;
		}
		fmc_word_program(address, data);
        fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR );
		address += 4;
		p += 4;
    }
	//写用户数据
	p = userInfo;
	len = sizeof(userInfo);
	address = EnvStore_UserInfoAddress;
	while(len > 0){
		memcpy(&data, p, sizeof(data));
		fmc_word_program(address, data);
		fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR );
		len -= 4;
		p += 4;
	}
    /* lock the main FMC after the erase operation */
    fmc_lock();
}

void EnvStore_GetUserInfo(uint8_t info[8]){
	memcpy(info, userInfo, 8);
}

